bitkeeper revision 1.259.2.1 (3f06d721WrVqlnf2Z2shaoLBGWSRng)
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Sat, 5 Jul 2003 13:48:17 +0000 (13:48 +0000)
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Sat, 5 Jul 2003 13:48:17 +0000 (13:48 +0000)
Many files:
  Removed 'hypercall-privilege-changing' functionality -- rings 2 & 3 will just have to bounce via ring 1. IOPL functionality has become a dom0_op, as it seems cleanest to have all privileged operations under one top-level syscall.

14 files changed:
xen/arch/i386/entry.S
xen/arch/i386/process.c
xen/arch/i386/traps.c
xen/common/dom0_ops.c
xen/include/asm-i386/processor.h
xen/include/hypervisor-ifs/dom0_ops.h
xen/include/hypervisor-ifs/hypervisor-if.h
xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_core.c
xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_ops.h
xenolinux-2.4.21-sparse/arch/xeno/kernel/ioport.c
xenolinux-2.4.21-sparse/arch/xeno/kernel/process.c
xenolinux-2.4.21-sparse/arch/xeno/kernel/setup.c
xenolinux-2.4.21-sparse/include/asm-xeno/hypervisor.h
xenolinux-2.4.21-sparse/include/asm-xeno/processor.h

index 33d533a28357dc2fc77cc565ef51ff65a84b5513..b60b5022885a31ea55e363a4181b115dea822480 100644 (file)
@@ -647,7 +647,6 @@ ENTRY(hypervisor_call_table)
         .long SYMBOL_NAME(do_dom_mem_op)
         .long SYMBOL_NAME(do_multicall)
         .long SYMBOL_NAME(do_kbd_op)
-        .long SYMBOL_NAME(do_set_priv_levels)
         .rept NR_syscalls-((.-hypervisor_call_table)/4)
         .long SYMBOL_NAME(sys_ni_syscall)
        .endr
index 695b58150758ec0c563249d57fc182310b8ac17c..5b604ca4135b0b0cf43ae93bee6c707291645af0 100644 (file)
@@ -348,19 +348,10 @@ void __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 }
 
 
-long do_set_priv_levels(unsigned int new_io_pl, unsigned int new_hypercall_pl)
+/* XXX Currently the 'domain' field is ignored! XXX */
+long do_iopl(unsigned int domain, unsigned int new_io_pl)
 {
     struct pt_regs *regs = GET_SYSCALL_REGS(current);
-
-    /*
-     * Any domain can reduce privilege required for hypercall access.
-     * Note that access from ring 1 cannot be relinquished.
-     */
-    current->thread.hypercall_pl = new_hypercall_pl & 3;
-
-    /* Only privileged domains can acquire access to I/O ports. */
-    if ( IS_PRIV(current) )
-        regs->eflags = (regs->eflags & 0xffffcfff) | ((new_io_pl&3) << 12);
-
+    regs->eflags = (regs->eflags & 0xffffcfff) | ((new_io_pl&3) << 12);
     return 0;
 }
index e4af21065b92e46d19ce571de7329040817bb421..8ca6b90ccffc74633c1aa1048033fa92ba7c3924 100644 (file)
@@ -401,23 +401,6 @@ asmlinkage void do_general_protection(struct pt_regs *regs, long error_code)
      */
     if ( (error_code & 3) == 2 )
     {
-        /*
-         * Hypercalls from rings 2 or 3 fall through to here. If permitted, we 
-         * will transfer control to the requested hypercall.
-         */
-        if ( ((error_code>>3) == HYPERVISOR_CALL_VECTOR) &&
-             (current->thread.hypercall_pl >= (regs->xcs & 3)) )
-        {
-            __asm__ __volatile__ (
-                "movl %0,%%esp                                         \n"
-                "sti                                                   \n"
-                "andl $255,%%eax                                       \n"
-                "call *hypervisor_call_table(,%%eax,4)                 \n"
-                "movl %%eax,0x18(%%esp)                                \n"
-                "jmp  ret_from_intr                                    \n"
-                : : "r" (regs) );
-        }
-
         /* This fault must be due to <INT n> instruction. */
         ti = current->thread.traps + (error_code>>3);
         if ( ti->dpl >= (regs->xcs & 3) )
index e65eeb0df1032d7e86b09f86d794c53fbe19ec3f..281fb509b967f2a8671128c16b952daaf15990fd 100644 (file)
@@ -67,7 +67,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
     long ret = 0;
     dom0_op_t op;
 
-    if ( current->domain != 0 )
+    if ( !IS_PRIV(current) )
         return -EPERM;
 
     if ( copy_from_user(&op, u_dom0_op, sizeof(op)) )
@@ -239,6 +239,13 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
         break;
     }
 
+    case DOM0_IOPL:
+    {
+        extern long do_iopl(unsigned int, unsigned int);
+        ret = do_iopl(op.u.iopl.domain, op.u.iopl.iopl);
+    }
+    break;
+
     default:
         ret = -ENOSYS;
 
index 80ec83e745e590a9ab91848530609a85e17d394e..eb0ca7001a06455b256081a752381756843e8d36 100644 (file)
@@ -356,7 +356,6 @@ struct thread_struct {
     int                 fast_trap_idx;
     struct desc_struct  fast_trap_desc;
     trap_info_t         traps[256];
-    int                 hypercall_pl;
 };
 
 #define IDT_ENTRIES 256
index d8da108d66af0b4f3d5e53e0c0fea34cca6bf1ef..b437acec26f54239a6f06c33ea1eb6df6793454d 100644 (file)
 #define DOM0_STOPDOMAIN    11
 #define DOM0_GETDOMAININFO 12
 #define DOM0_BUILDDOMAIN   13
+#define DOM0_IOPL          14
 
-#define MAX_CMD_LEN    256
-#define MAX_DOMAIN_NAME 16
+#define MAX_CMD_LEN       256
+#define MAX_DOMAIN_NAME    16
 
 typedef struct dom0_newdomain_st 
 {
@@ -60,32 +61,38 @@ typedef struct domain_launch
 
 typedef struct dom0_bvtctl_st
 {
-       unsigned long ctx_allow;        /* context switch allowance */
+    unsigned long ctx_allow;   /* context switch allowance */
 } dom0_bvtctl_t;
 
 typedef struct dom0_adjustdom_st
 {
     unsigned int  domain;      /* domain id */
-       unsigned long mcu_adv;  /* mcu advance: inverse of weight */
-       unsigned long warp;     /* time warp */
-       unsigned long warpl;    /* warp limit */
-       unsigned long warpu;    /* unwarp time requirement */
+    unsigned long mcu_adv;     /* mcu advance: inverse of weight */
+    unsigned long warp;     /* time warp */
+    unsigned long warpl;    /* warp limit */
+    unsigned long warpu;    /* unwarp time requirement */
 } dom0_adjustdom_t;
 
 typedef struct dom0_getdominfo_st
 {
-  unsigned int domain;          /* All returns except domain */
-  char name[MAX_DOMAIN_NAME];
-  int processor;
-  int has_cpu;
-  int state;
-  int hyp_events;
-  unsigned long mcu_advance;
-  unsigned long pg_head;
-  unsigned int tot_pages;
-  long long cpu_time;
+    unsigned int domain;          /* All returns except domain */
+    char name[MAX_DOMAIN_NAME];
+    int processor;
+    int has_cpu;
+    int state;
+    int hyp_events;
+    unsigned long mcu_advance;
+    unsigned long pg_head;
+    unsigned int tot_pages;
+    long long cpu_time;
 } dom0_getdominfo_t;
 
+typedef struct dom0_iopl_st
+{
+    unsigned int domain;
+    unsigned int iopl;
+} dom0_iopl_t;
+
 #ifndef NO_DOM0_OP_T
 typedef struct dom0_op_st
 {
@@ -95,11 +102,12 @@ typedef struct dom0_op_st
         dom0_newdomain_t newdomain;
         dom0_killdomain_t killdomain;
         dom0_getmemlist_t getmemlist;
-               dom0_bvtctl_t bvtctl;
-               dom0_adjustdom_t adjustdom;
+        dom0_bvtctl_t bvtctl;
+        dom0_adjustdom_t adjustdom;
         dom_meminfo_t meminfo;
         dom0_getdominfo_t getdominfo;
-   }
+        dom0_iopl_t iopl;
+    }
     u;
 } dom0_op_t;
 #endif
index 2516f84554ad41ce0006db72003f0d0e51e26454..0dfd07cb6011f83120d8963737a893cfad3f92ec 100644 (file)
@@ -48,7 +48,6 @@
 #define __HYPERVISOR_dom_mem_op                  17
 #define __HYPERVISOR_multicall           18
 #define __HYPERVISOR_kbd_op               19
-#define __HYPERVISOR_set_priv_levels      20
 
 /* And the trap vector is... */
 #define TRAP_INSTR "int $0x82"
index b42abc45e4fac77b927eb5ae850c1c8f88001c6b..1aa5ef0d54c25a4df4ec73c5ea274740722674fe 100644 (file)
@@ -334,12 +334,6 @@ static int cmd_write_proc(struct file *file, const char *buffer,
     
     copy_from_user(&op, buffer, sizeof(dom0_op_t));
 
-    /* do some sanity checks */
-    if(op.cmd > MAX_CMD){
-        ret = -ENOSYS;
-        goto out;
-    }
-
     if ( op.cmd == MAP_DOM_MEM )
     {
         ret = dom_map_mem(op.u.dommem.domain, op.u.dommem.start_pfn, 
index 8562591e1ea9370895a52431eae293af1065a02a..23006eae0daa1c86f7d25b495e47d677d721df49 100644 (file)
@@ -18,9 +18,8 @@
 #endif
 
 /* Extra commands dealt with by Xenolinux. */
-#define MAP_DOM_MEM        14
-#define DO_PGUPDATES       15
-#define MAX_CMD            16
+#define MAP_DOM_MEM        1014
+#define DO_PGUPDATES       1015
 
 typedef struct dom_mem 
 {
@@ -50,8 +49,8 @@ typedef struct dom0_op_st
         dom_pgupdate_t pgupdate;
         dom_meminfo_t meminfo;
         dom0_getdominfo_t getdominfo;
-   }
-    u;
+        dom0_iopl_t iopl;
+   } u;
 } dom0_op_t;
 
 #endif /* __DOM0_DOM0_OPS_H__ */
index 7b30b8dcf2bd03045bbb212f6635bfab099a7eef..c946fc4d37cdbdafe730512be77d0eac1a08c322 100644 (file)
@@ -3,6 +3,7 @@
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/stddef.h>
+#include <asm/hypervisor-ifs/dom0_ops.h>
 
 
 asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int turn_on)
@@ -15,32 +16,32 @@ asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int turn_on)
 asmlinkage int sys_iopl(unsigned long unused)
 {
     struct pt_regs *regs = (struct pt_regs *)&unused;
-    unsigned int new_io_pl = regs->ebx & 3;
+    unsigned int new_io_pl = regs->ebx;
     unsigned int old_io_pl = current->thread.io_pl;
-    unsigned int new_hypercall_pl = (regs->ebx >> 2) & 3;
-    unsigned int old_hypercall_pl = current->thread.hypercall_pl;
+    dom0_op_t op;
 
-    /* Need "raw I/O" privileges for direct port access. */
-    if ( (new_io_pl > old_io_pl) && 
-         (!capable(CAP_SYS_RAWIO) || !(start_info.flags & SIF_PRIVILEGED)) )
+    if ( !(start_info.flags & SIF_PRIVILEGED) )
         return -EPERM;
 
-    /* Just need generic root/admin privileges for direct hypercall access. */
-    if ( (new_hypercall_pl > old_hypercall_pl) && !capable(CAP_SYS_ADMIN) )
+    if ( new_io_pl > 3 )
+        return -EINVAL;
+
+    /* Need "raw I/O" privileges for direct port access. */
+    if ( (new_io_pl > old_io_pl) && !capable(CAP_SYS_RAWIO) )
         return -EPERM;
 
     /* Maintain OS privileges even if user attempts to relinquish them. */
-    if ( new_hypercall_pl == 0 )
-        new_hypercall_pl = 1;
     if ( (new_io_pl == 0) && (start_info.flags & SIF_PRIVILEGED) )
         new_io_pl = 1;
 
     /* Change our version of the privilege levels. */
-    current->thread.io_pl        = new_io_pl;
-    current->thread.hypercall_pl = new_hypercall_pl;
+    current->thread.io_pl = new_io_pl;
 
     /* Force the change at ring 0. */
-    HYPERVISOR_set_priv_levels(new_io_pl, new_hypercall_pl);
+    op.cmd           = DOM0_IOPL;
+    op.u.iopl.domain = start_info.dom_id;
+    op.u.iopl.iopl   = new_io_pl;
+    HYPERVISOR_dom0_op(&op);
 
     return 0;
 }
index 06cb7a356342bb0a5dde3bf4e4a00009a42a1a68..86f8e680f4e06b219b312584c91ef81c3fa48388 100644 (file)
@@ -44,6 +44,7 @@
 #include <asm/desc.h>
 #include <asm/mmu_context.h>
 #include <asm/multicall.h>
+#include <asm/hypervisor-ifs/dom0_ops.h>
 
 #include <linux/irq.h>
 
@@ -274,9 +275,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
     __asm__ __volatile__ ( "pushfl; popl %0" : "=r" (eflags) : );
     p->thread.io_pl = (eflags >> 12) & 3;
 
-    /* We're careful with hypercall privileges. Don't allow inheritance. */
-    p->thread.hypercall_pl = 1;
-
     return 0;
 }
 
@@ -371,9 +369,14 @@ void __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
     }
 
     queue_multicall2(__HYPERVISOR_stack_switch, __KERNEL_DS, next->esp0);
-    /* Next call will silently fail if we are a non-privileged guest OS. */
-    queue_multicall2(__HYPERVISOR_set_priv_levels,
-                     next->io_pl, next->hypercall_pl);
+    if ( start_info.flags & SIF_PRIVILEGED ) 
+    {
+        dom0_op_t op;
+        op.cmd           = DOM0_IOPL;
+        op.u.iopl.domain = start_info.dom_id;
+        op.u.iopl.iopl   = next->io_pl;
+        queue_multicall1(__HYPERVISOR_dom0_op, (unsigned long)&op);
+    }
 
     /* EXECUTE ALL TASK SWITCH XEN SYSCALLS AT THIS POINT. */
     execute_multicall_list();
index 0c3474e4caa8500e1f39c06337a0a3cb8b9d68ea..80f55c6cb6befdf20d3869e642e3edeae5f8afa0 100644 (file)
@@ -43,6 +43,7 @@
 #include <asm/mpspec.h>
 #include <asm/mmu_context.h>
 #include <asm/hypervisor.h>
+#include <asm/hypervisor-ifs/dom0_ops.h>
 
 shared_info_t *HYPERVISOR_shared_info;
 
@@ -301,12 +302,16 @@ void __init setup_arch(char **cmdline_p)
 
     paging_init();
 
-    current->thread.hypercall_pl = 1;
-    if ( start_info.flags & SIF_PRIVILEGED ) {
-        current->thread.io_pl = 1;
-        /* We are privileged guest os - should have IO privileges. */
-        if( HYPERVISOR_set_priv_levels(1, 1) )
+    /* We are privileged guest os - should have IO privileges. */
+    if ( start_info.flags & SIF_PRIVILEGED ) 
+    {
+        dom0_op_t op;
+        op.cmd           = DOM0_IOPL;
+        op.u.iopl.domain = start_info.dom_id;
+        op.u.iopl.iopl   = 1;
+        if( HYPERVISOR_dom0_op(&op) != 0 )
             panic("Unable to obtain IOPL, despite being SIF_PRIVILEGED");
+        current->thread.io_pl = 1;
     }
 
     if(start_info.flags & SIF_CONSOLE)
index da0e1a19e0a699dbe8f0e4159d5f3079aaa72cad..abf109b2cacdba55b4e18556a412ecc972a137f0 100644 (file)
@@ -364,16 +364,4 @@ static inline long HYPERVISOR_kbd_op(unsigned char op, unsigned char val)
     return ret;
 }
 
-static inline long HYPERVISOR_set_priv_levels(unsigned int new_io_pl,
-                                              unsigned int new_hypercall_pl)
-{
-    int ret;
-    __asm__ __volatile__ (
-        TRAP_INSTR
-        : "=a" (ret) : "0" (__HYPERVISOR_set_priv_levels),
-        "b" (new_io_pl), "c" (new_hypercall_pl) );
-
-    return ret;
-}
-
 #endif /* __HYPERVISOR_H__ */
index 3c4fa92b4188b5a30edb41b6424d340b63b75881..c47e348c53f36074184df18d78ee8625c23b34a1 100644 (file)
@@ -358,7 +358,7 @@ struct thread_struct {
        unsigned long   esp;
        unsigned long   fs;
        unsigned long   gs;
-       unsigned int    io_pl, hypercall_pl;
+       unsigned int    io_pl;
 /* Hardware debugging registers */
        unsigned long   debugreg[8];  /* %%db0-7 debug registers */
 /* fault info */